"""
配图建议生成器
分析文章内容，生成图片需求和配图建议
"""

import re
from typing import Dict, List, Tuple, Optional, Any
from dataclasses import dataclass
from enum import Enum
import logging

logger = logging.getLogger(__name__)


class ImageType(Enum):
    """图片类型"""
    INFOGRAPHIC = "infographic"      # 信息图
    CHART = "chart"                  # 图表
    PHOTO = "photo"                  # 照片
    ILLUSTRATION = "illustration"    # 插画
    SCREENSHOT = "screenshot"        # 截图
    DIAGRAM = "diagram"              # 图解
    FLOWCHART = "flowchart"         # 流程图
    MINDMAP = "mindmap"              # 思维导图


@dataclass
class ImagePosition:
    """图片位置建议"""
    paragraph_index: int
    position: str  # before, after, within
    reason: str


@dataclass
class ImageSuggestion:
    """配图建议"""
    type: ImageType
    title: str
    description: str
    keywords: List[str]
    alt_text: str
    caption: str
    position: ImagePosition
    priority: str  # high, medium, low
    data_requirements: List[str]


@dataclass
class ImageAnalysisResult:
    """配图分析结果"""
    total_paragraphs: int
    suggested_image_count: int
    suggestions: List[ImageSuggestion]
    image_density_score: float
    visual_appeal_score: float
    recommendations: List[Dict[str, Any]]


class ImageSuggester:
    """配图建议生成器"""
    
    def __init__(self):
        """初始化生成器"""
        # 理想的图文比例
        self.ideal_image_ratio = 0.3  # 每3-4段文字配1张图
        
        # 数据可视化触发词
        self.data_keywords = [
            '数据', '统计', '比例', '增长', '下降', '对比', '趋势',
            '百分比', '%', '数字', '调查', '报告', '分析', '研究',
            '第一', '第二', '排名', 'TOP', '占比', '份额'
        ]
        
        # 流程相关触发词
        self.process_keywords = [
            '步骤', '流程', '过程', '阶段', '首先', '然后', '最后',
            '第一步', '第二步', '顺序', '环节', '方法', '操作'
        ]
        
        # 概念说明触发词
        self.concept_keywords = [
            '原理', '机制', '结构', '组成', '架构', '框架', '模型',
            '关系', '层次', '体系', '要素', '核心', '基础'
        ]
        
        # 对比相关触发词
        self.comparison_keywords = [
            '对比', '比较', '区别', '差异', '相同', '不同', '优缺点',
            '优势', '劣势', 'VS', '对照', '而', '但是', '然而'
        ]
        
        # 配图位置规则
        self.position_rules = {
            'header': ['标题', '引言', '摘要', '导语'],
            'section_start': ['第一', '第二', '第三', '其一', '其二'],
            'data_visual': self.data_keywords,
            'process_flow': self.process_keywords,
            'concept_explain': self.concept_keywords
        }
    
    def suggest(self, content: str, title: str = "") -> ImageAnalysisResult:
        """
        生成配图建议
        
        Args:
            content: 文章内容
            title: 文章标题
            
        Returns:
            配图分析结果
        """
        if not content or not content.strip():
            return self._empty_result("内容为空")
        
        # 分段
        paragraphs = self._split_paragraphs(content)
        
        # 分析每段内容
        suggestions = []
        
        # 为标题建议配图
        if title:
            title_suggestion = self._suggest_for_title(title)
            if title_suggestion:
                suggestions.append(title_suggestion)
        
        # 分析段落
        for i, paragraph in enumerate(paragraphs):
            para_suggestions = self._analyze_paragraph(paragraph, i)
            suggestions.extend(para_suggestions)
        
        # 计算图片密度
        image_density_score = self._calculate_density_score(
            len(suggestions), len(paragraphs)
        )
        
        # 计算视觉吸引力
        visual_appeal_score = self._calculate_visual_appeal(suggestions)
        
        # 生成推荐
        recommendations = self._generate_recommendations(
            suggestions, len(paragraphs), image_density_score
        )
        
        return ImageAnalysisResult(
            total_paragraphs=len(paragraphs),
            suggested_image_count=len(suggestions),
            suggestions=suggestions,
            image_density_score=image_density_score,
            visual_appeal_score=visual_appeal_score,
            recommendations=recommendations
        )
    
    def _split_paragraphs(self, content: str) -> List[str]:
        """分割段落"""
        paragraphs = content.split('\n\n')
        return [p.strip() for p in paragraphs if p.strip()]
    
    def _suggest_for_title(self, title: str) -> Optional[ImageSuggestion]:
        """为标题生成配图建议"""
        # 提取关键词
        keywords = self._extract_keywords_from_text(title)
        
        return ImageSuggestion(
            type=ImageType.PHOTO,
            title="文章封面图",
            description=f"与'{title}'主题相关的视觉化表现",
            keywords=keywords,
            alt_text=title,
            caption=f"{title} - 配图",
            position=ImagePosition(
                paragraph_index=0,
                position="before",
                reason="文章开头需要吸引眼球的封面图"
            ),
            priority="high",
            data_requirements=[]
        )
    
    def _analyze_paragraph(self, paragraph: str, index: int) -> List[ImageSuggestion]:
        """分析段落生成配图建议"""
        suggestions = []
        
        # 检查是否包含数据
        if self._contains_data(paragraph):
            suggestion = self._create_data_visualization(paragraph, index)
            if suggestion:
                suggestions.append(suggestion)
        
        # 检查是否包含流程
        elif self._contains_process(paragraph):
            suggestion = self._create_process_diagram(paragraph, index)
            if suggestion:
                suggestions.append(suggestion)
        
        # 检查是否包含概念说明
        elif self._contains_concept(paragraph):
            suggestion = self._create_concept_illustration(paragraph, index)
            if suggestion:
                suggestions.append(suggestion)
        
        # 检查是否包含对比
        elif self._contains_comparison(paragraph):
            suggestion = self._create_comparison_chart(paragraph, index)
            if suggestion:
                suggestions.append(suggestion)
        
        # 长段落考虑配图
        elif len(paragraph) > 500:
            suggestion = self._create_generic_illustration(paragraph, index)
            if suggestion:
                suggestions.append(suggestion)
        
        return suggestions
    
    def _contains_data(self, text: str) -> bool:
        """检查是否包含数据内容"""
        return any(keyword in text for keyword in self.data_keywords)
    
    def _contains_process(self, text: str) -> bool:
        """检查是否包含流程内容"""
        return any(keyword in text for keyword in self.process_keywords)
    
    def _contains_concept(self, text: str) -> bool:
        """检查是否包含概念说明"""
        return any(keyword in text for keyword in self.concept_keywords)
    
    def _contains_comparison(self, text: str) -> bool:
        """检查是否包含对比内容"""
        return any(keyword in text for keyword in self.comparison_keywords)
    
    def _create_data_visualization(self, paragraph: str, index: int) -> Optional[ImageSuggestion]:
        """创建数据可视化建议"""
        # 提取数据点
        numbers = re.findall(r'\d+\.?\d*%?', paragraph)
        keywords = self._extract_keywords_from_text(paragraph)
        
        # 判断图表类型
        if '%' in paragraph or '百分比' in paragraph or '占比' in paragraph:
            chart_type = ImageType.CHART
            title = "数据占比图"
            description = "饼图或柱状图展示数据占比"
        elif '增长' in paragraph or '下降' in paragraph or '趋势' in paragraph:
            chart_type = ImageType.CHART
            title = "趋势变化图"
            description = "折线图展示数据趋势"
        else:
            chart_type = ImageType.INFOGRAPHIC
            title = "数据信息图"
            description = "信息图展示关键数据"
        
        return ImageSuggestion(
            type=chart_type,
            title=title,
            description=description,
            keywords=keywords,
            alt_text=f"第{index+1}段数据可视化",
            caption=self._generate_caption(paragraph, "数据"),
            position=ImagePosition(
                paragraph_index=index,
                position="after",
                reason="数据内容需要可视化展示"
            ),
            priority="high",
            data_requirements=numbers
        )
    
    def _create_process_diagram(self, paragraph: str, index: int) -> Optional[ImageSuggestion]:
        """创建流程图建议"""
        keywords = self._extract_keywords_from_text(paragraph)
        
        # 提取步骤
        steps = []
        step_patterns = [r'第[一二三四五六七八九十\d]+步?', r'\d+\.', r'首先|然后|接着|最后']
        for pattern in step_patterns:
            matches = re.findall(pattern, paragraph)
            steps.extend(matches)
        
        return ImageSuggestion(
            type=ImageType.FLOWCHART,
            title="流程示意图",
            description="流程图展示操作步骤或过程",
            keywords=keywords,
            alt_text=f"第{index+1}段流程图",
            caption=self._generate_caption(paragraph, "流程"),
            position=ImagePosition(
                paragraph_index=index,
                position="after",
                reason="流程说明需要图解"
            ),
            priority="medium",
            data_requirements=steps
        )
    
    def _create_concept_illustration(self, paragraph: str, index: int) -> Optional[ImageSuggestion]:
        """创建概念插图建议"""
        keywords = self._extract_keywords_from_text(paragraph)
        
        return ImageSuggestion(
            type=ImageType.DIAGRAM,
            title="概念示意图",
            description="图解说明核心概念或架构",
            keywords=keywords,
            alt_text=f"第{index+1}段概念图",
            caption=self._generate_caption(paragraph, "示意"),
            position=ImagePosition(
                paragraph_index=index,
                position="after",
                reason="抽象概念需要图解辅助理解"
            ),
            priority="medium",
            data_requirements=[]
        )
    
    def _create_comparison_chart(self, paragraph: str, index: int) -> Optional[ImageSuggestion]:
        """创建对比图表建议"""
        keywords = self._extract_keywords_from_text(paragraph)
        
        return ImageSuggestion(
            type=ImageType.CHART,
            title="对比分析图",
            description="对比图表展示差异和优劣",
            keywords=keywords,
            alt_text=f"第{index+1}段对比图",
            caption=self._generate_caption(paragraph, "对比"),
            position=ImagePosition(
                paragraph_index=index,
                position="after",
                reason="对比内容适合图表展示"
            ),
            priority="medium",
            data_requirements=[]
        )
    
    def _create_generic_illustration(self, paragraph: str, index: int) -> Optional[ImageSuggestion]:
        """创建通用插图建议"""
        keywords = self._extract_keywords_from_text(paragraph)
        
        # 长段落每隔一定间隔建议配图
        if index % 3 == 0:  # 每3段建议一张图
            return ImageSuggestion(
                type=ImageType.ILLUSTRATION,
                title="配图插画",
                description="相关主题的插画或照片",
                keywords=keywords,
                alt_text=f"第{index+1}段配图",
                caption="",
                position=ImagePosition(
                    paragraph_index=index,
                    position="after",
                    reason="长文本需要视觉元素调节阅读节奏"
                ),
                priority="low",
                data_requirements=[]
            )
        
        return None
    
    def _extract_keywords_from_text(self, text: str) -> List[str]:
        """从文本提取关键词"""
        # 简化版关键词提取
        words = re.findall(r'[\u4e00-\u9fff]{2,4}', text)
        
        # 过滤停用词
        stopwords = {'的', '是', '在', '和', '了', '有', '我', '你', '他'}
        keywords = [w for w in words if w not in stopwords]
        
        # 返回前5个高频词
        from collections import Counter
        word_freq = Counter(keywords)
        return [word for word, _ in word_freq.most_common(5)]
    
    def _generate_caption(self, paragraph: str, image_type: str) -> str:
        """生成图片说明"""
        # 提取第一句话作为基础
        first_sentence = paragraph.split('。')[0] if '。' in paragraph else paragraph[:50]
        
        # 根据图片类型生成说明
        if image_type == "数据":
            return f"图：{first_sentence}的数据展示"
        elif image_type == "流程":
            return f"图：{first_sentence}的流程示意"
        elif image_type == "对比":
            return f"图：{first_sentence}的对比分析"
        else:
            return f"图：{first_sentence}"
    
    def _calculate_density_score(self, image_count: int, paragraph_count: int) -> float:
        """计算图片密度分数"""
        if paragraph_count == 0:
            return 0.0
        
        actual_ratio = image_count / paragraph_count
        
        # 理想比例的偏差
        deviation = abs(actual_ratio - self.ideal_image_ratio)
        
        # 转换为0-1分数
        score = max(0, 1 - deviation * 2)
        
        return score
    
    def _calculate_visual_appeal(self, suggestions: List[ImageSuggestion]) -> float:
        """计算视觉吸引力分数"""
        if not suggestions:
            return 0.0
        
        score = 0.0
        
        # 图片类型多样性
        unique_types = set(s.type for s in suggestions)
        diversity_score = len(unique_types) / len(ImageType)
        score += diversity_score * 0.3
        
        # 高优先级图片比例
        high_priority = sum(1 for s in suggestions if s.priority == "high")
        priority_score = high_priority / len(suggestions)
        score += priority_score * 0.4
        
        # 数据可视化比例（更重要）
        data_visuals = sum(1 for s in suggestions 
                          if s.type in [ImageType.CHART, ImageType.INFOGRAPHIC])
        data_score = data_visuals / len(suggestions) if suggestions else 0
        score += data_score * 0.3
        
        return min(1.0, score)
    
    def _generate_recommendations(self, suggestions: List[ImageSuggestion],
                                 paragraph_count: int,
                                 density_score: float) -> List[Dict[str, Any]]:
        """生成配图建议"""
        recommendations = []
        
        # 图片数量建议
        ideal_count = int(paragraph_count * self.ideal_image_ratio)
        actual_count = len(suggestions)
        
        if actual_count < ideal_count * 0.5:
            recommendations.append({
                "type": "quantity",
                "priority": "high",
                "description": "增加配图数量",
                "detail": f"当前{actual_count}张，建议增加到{ideal_count}张左右",
                "tips": [
                    "在数据说明处添加图表",
                    "在流程说明处添加流程图",
                    "在长段落后添加相关插图"
                ]
            })
        elif actual_count > ideal_count * 1.5:
            recommendations.append({
                "type": "quantity",
                "priority": "medium",
                "description": "精简配图数量",
                "detail": f"当前{actual_count}张，建议控制在{ideal_count}张左右",
                "tips": [
                    "合并相似的图表",
                    "删除装饰性图片",
                    "保留信息量大的图片"
                ]
            })
        
        # 图片类型建议
        type_counts = {}
        for s in suggestions:
            type_counts[s.type] = type_counts.get(s.type, 0) + 1
        
        if ImageType.CHART not in type_counts and any('数据' in s.description for s in suggestions):
            recommendations.append({
                "type": "variety",
                "priority": "medium",
                "description": "添加数据图表",
                "detail": "文章包含数据内容，建议添加图表可视化",
                "examples": ["柱状图", "折线图", "饼图"]
            })
        
        # 位置分布建议
        if suggestions:
            first_image_index = min(s.position.paragraph_index for s in suggestions)
            if first_image_index > 2:
                recommendations.append({
                    "type": "position",
                    "priority": "high",
                    "description": "在文章开头添加配图",
                    "detail": "前面段落缺少配图，影响初始阅读体验",
                    "suggestion": "在标题或第一段后添加主题图片"
                })
        
        # 图片质量建议
        if density_score < 0.5:
            recommendations.append({
                "type": "balance",
                "priority": "medium",
                "description": "优化图文比例",
                "detail": "图片分布不均匀，建议调整位置",
                "tips": [
                    "确保重要段落都有配图",
                    "避免图片过于集中",
                    "保持图文节奏感"
                ]
            })
        
        return recommendations
    
    def _empty_result(self, reason: str) -> ImageAnalysisResult:
        """返回空结果"""
        return ImageAnalysisResult(
            total_paragraphs=0,
            suggested_image_count=0,
            suggestions=[],
            image_density_score=0.0,
            visual_appeal_score=0.0,
            recommendations=[{
                "type": "error",
                "priority": "high",
                "description": reason,
                "detail": "",
                "tips": []
            }]
        )